// 解决栈溢出问题, 问题描述: obj.age++, 则会陷入死循环!
let activeEffect
const data = {num: 0}
const bucket = new WeakMap()
// 新增
let effectStack = []

// 收集依赖
function track (target, key) {
  let depsMap = bucket.get(target)
  if (!depsMap) {
    bucket.set(target, depsMap = new Map())
  }
  let deps = depsMap.get(key)
  if (!deps) {
    depsMap.set(key, deps = new Set())
  }
  if (activeEffect) {
    deps.add(activeEffect)
    activeEffect.deps.push(deps)
  }
}

// 触发事件
function trigger (target, key) {
  const depsMap = bucket.get(target)
  if (!depsMap) return
  const effects = depsMap.get(key)
  // ==== 修改如下
  // 将effectsToRun改为一个空的Set, 然后循环副作用集合effects
  // 将和activeEffect不同的effect加入effectsToRun执行
  const effectsToRun = new Set()
  // effectsToRun.forEach(effect => effect())
  effects.forEach(effect => {
    if (effect !== activeEffect) {
      effectsToRun.add(effect)
    }
  })
  effectsToRun.forEach(effect => effect())
}

// 代理
const obj = new Proxy(data, {
  get(target, key) {
    track(target, key)
    return target[key]
  },
  set(target, key, value) {
    target[key] = value
    trigger(target, key)
  }
})

function cleanup (effectFn) {
  for (let i = 0; i < effectFn.deps.length; i++) {
    const deps = effectFn.deps[i]
    deps.delete(effectFn)
  }
  effectFn.deps.length = 0
}

function effect (fn) {
  const effectFn = () => {
    cleanup(effectFn)
    activeEffect = effectFn
    effectStack.push(effectFn)
    fn()
    effectStack.pop()
    activeEffect = effectStack[effectStack.length - 1]
  }
  effectFn.deps = []
  effectFn()
}

effect(() => {
  obj.num++
  console.log(obj.num,'num')
})


/**
 * 解析:
 * 在执行的时候, 将当前的副作用函数过滤掉!
 */